package org.teamh.gui.ingame;

import static org.lwjgl.opengl.GL11.*;

import org.lwjgl.input.Keyboard;
import org.teamh.connection.json.NOOP;
import org.teamh.connection.json.handler.JsonConnectionHandler;
import org.teamh.gui.Event;
import org.teamh.gui.GUI;
import org.teamh.gui.Screen;
import org.teamh.gui.engine.ogg.BackgroundMusic;
import org.teamh.gui.ingame.effects.CreepLife;
import org.teamh.gui.ingame.effects.EffectManager;
import org.teamh.gui.ingame.effects.ShotManager;
import org.teamh.gui.ingame.effects.TowerUpgradeProgress;
import org.teamh.logic.datamodel.Creep;
import org.teamh.logic.datamodel.DatamodelManager;
import org.teamh.logic.datamodel.Tile;
import org.teamh.logic.datamodel.UserAssets;

import de.lessvoid.nifty.controls.Button;

public class IngameScreen implements Screen {
	private GUI gui;
	private DatamodelManager model;
	private IngameScreenHUD ingameScreenHUD;
	private IngameFunctions ingameFunctions;
	private ShotManager shotManager;
	
	public IngameScreen(GUI gui) {
		this.gui = gui;
		this.ingameFunctions = new IngameFunctions(gui);
		this.ingameScreenHUD= new IngameScreenHUD(gui);
		this.shotManager = new ShotManager(gui);
		
		BackgroundMusic.get().setMusic("res/sound/Tower Defense Music.ogg");
	}

	@Override
	public void build(){
		ingameScreenHUD.build();
	}

	@Override
	public void render(float timeElapsed) {
		//check, if a shot occurs
		shotManager.update();
		
		//render environment for picking
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glLoadIdentity();
		ingameFunctions.renderForPicking();
		
		//render environment for drawing on the screen. 
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glLoadIdentity();
		ingameFunctions.render(timeElapsed);
		
		//update the chat manager for removing old chat messages
		ingameScreenHUD.getChatManager().update();
		
		//update the backgroundmusic
		if(getIngameScreenHUD().getController().getStart()) {
			BackgroundMusic.get().update();
		}
	}
	
	@Override
	public void init() {
		model=ingameFunctions.getGui().getStart().getLogic().getManager();
		new LoadWorld(model);
		ingameFunctions.init();
		for(UserAssets user: gui.getStart().getLogic().getManager().getUserAssets().values()) {
			if(user.getTile() == null || user.getUser() == null || user.getUser().getNickname() == null) {
				continue;
			}
			
			String pos = user.getTile().getPosition();
			
			if(pos.equals("TOP_LEFT")) {
				ingameScreenHUD.getChatManager().setUpperLeftPlayer(user.getUser().getNickname(),user.getUser().getTeam().getName(), user.getLives());
			} else if(pos.equals("BOTTOM_LEFT")) {
				ingameScreenHUD.getChatManager().setLowerLeftPlayer(user.getUser().getNickname(),user.getUser().getTeam().getName(), user.getLives());
			} else if(pos.equals("TOP_RIGHT")) {
				ingameScreenHUD.getChatManager().setUpperRightPlayer(user.getUser().getNickname(),user.getUser().getTeam().getName(), user.getLives());
			} else if(pos.equals("BOTTOM_RIGHT")) {
				ingameScreenHUD.getChatManager().setLowerRightPlayer(user.getUser().getNickname(),user.getUser().getTeam().getName(), user.getLives());
			} else {
				//should not happen
			}
		}
	}

	@Override
	public void keyPressed(int key) {
		ingameScreenHUD.getChatManager().keyPressed(key);
		
		ingameScreenHUD.getController().getLeaveGameScreen().keyPressed(key);
		if(key == Keyboard.KEY_F2) {
			if(BackgroundMusic.get().getMaxVolume() == 0) {
				BackgroundMusic.get().setMaxVolume(1);
			} else {
				BackgroundMusic.get().setMaxVolume(0);
			}
		}
	}

	@Override
	public void keyReleased(int key) {
		
	}

	@Override
	public void mousePressed(int posX, int posY, int button) {
		ingameFunctions.mousePressed(posX, posY, button);
	}

	@Override
	public void mouseReleased(int posX, int posY, int button) {
		ingameFunctions.mouseReleased(posX, posY, button);
	}

	@Override
	public void mouseMoved(int posX, int posY, int button) {
		ingameFunctions.mouseMoved(posX, posY, button);
	}

	@Override
	public void mouseDragged(int posX, int posY, int button) {
		ingameFunctions.mouseDragged(posX, posY, button);
	}

	@Override
	public void mouseWheelMoved(int movement) {
		ingameFunctions.mouseWheelMoved(movement);
	}

	@Override
	public void dealloc() {
		if(gui.getStart().getConnection().getMessageReceiver() instanceof JsonConnectionHandler) {
			NOOP.stop();
		}
	}

	@Override
	public void eventOccured(Event event) {
		//tile has been choosen by someone, so grey out this tile
		if (event.getKey().equals("tile")) {
			String[] split = event.getValue().split(" ");
			@SuppressWarnings("unused")
			String tilePostionString = split[0];
			
			//TODO: this is a ******* server bug!! 
			if(null == gui.getStart().getLogic().getManager().getTile(split[1]).getUserAssets() || gui.getStart().getLogic().getManager().getTile(split[1]).getUserAssets().getUser() == null) {
				return;
			};
			
			boolean allTilesSelected = true;
			for(Tile t: gui.getStart().getLogic().getManager().getTiles().values()) {
				if(t.getUserAssets() != null && t.getUserAssets().getUser() != null) {
					//TODO: this happens when another user is entering the ingame screen!!!!
					UserAssets userAssets = t.getUserAssets();
					if(t.getPosition() == null || userAssets == null || userAssets.getUser().getNickname() == null || userAssets.getUser().getTeam() == null || userAssets.getUser().getTeam().getName() == null) {
						continue;
					}
					
					setPlayer(t.getPosition(), userAssets.getUser().getNickname(), "<" + userAssets.getUser().getTeam().getName() + ">", userAssets.getLives());
					ingameScreenHUD.getController().enableRed(t.getPosition());
					ingameScreenHUD.getController().fillselectedTiles(t.getPosition());
				} else {
					allTilesSelected = false;
					setPlayer(t.getPosition(), "", "", 0);
					ingameScreenHUD.getController().disableRed(t.getPosition());
					ingameScreenHUD.getController().defillselectedTiles(t.getPosition());
				}
			}
			if(allTilesSelected) {
				ingameScreenHUD.getController().getIngameScreen().findNiftyControl("startButtonTower", Button.class).enable();
				ingameScreenHUD.getController().getIngameScreen().findNiftyControl("startButtonCreep", Button.class).enable();
			}
			
		} else if(event.getKey().equals("chatMessage")) {
			String[] split = event.getValue().split("#");
			ingameScreenHUD.getChatManager().displayMessage(split[0], split[1], split[2], Integer.parseInt(split[3]));
		} else if(event.getKey().equals("closed")) {
			ingameScreenHUD.getController().leaveGame();
		} else if(event.getKey().equals("gold")) {
			ingameScreenHUD.getController().updateGold(event.getValue());
		} else if(event.getKey().equals("running")) {
			ingameScreenHUD.getController().startGame();
		} else if(event.getKey().equals("lives")) {
			ingameScreenHUD.getController().updateLives(event.getValue());
		} else if(event.getKey().equals("upgradeTower")) {
			EffectManager.get().addEffect(new TowerUpgradeProgress(event.getValue()));
		} else if(event.getKey().equals("updateLives")) {
			ingameScreenHUD.getChatManager().updateLives();
		} else if(event.getKey().equals("creepCreated")) {
			Creep creep = gui.getStart().getLogic().getManager().getCreep(event.getValue());
			if(creep != null) {
				EffectManager.get().addEffect(new CreepLife(creep));
			}
		} else if(event.getKey().equals("winner")) {
			ingameScreenHUD.getController().setWinner(event.getValue());
		}
	}
	
	private void setPlayer(String position, String userName, String team, int lives) {
		if (position.equals("TOP_LEFT")) {
			ingameScreenHUD.getChatManager().setUpperLeftPlayer(userName, team, lives);
		} else if (position.equals("TOP_RIGHT")) {
			ingameScreenHUD.getChatManager().setUpperRightPlayer(userName, team, lives);
		} else if (position.equals("BOTTOM_LEFT")) {
			ingameScreenHUD.getChatManager().setLowerLeftPlayer(userName, team, lives);
		} else if (position.equals("BOTTOM_RIGHT")) {
			ingameScreenHUD.getChatManager().setLowerRightPlayer(userName, team, lives);
		}
	}
	
	public IngameFunctions getIngameFunctions() {
		return ingameFunctions;
	}
	
	public IngameScreenHUD getIngameScreenHUD() {
		return ingameScreenHUD;
	}
	
	public boolean canPoll() {
		return true;
	}
	
	@Override
	public String getNiftyScreenID() {
		return "ingameScreen";
	}
}
